package com.example.utils;

import ch.qos.logback.classic.boolex.ExceptionMatchEvaluator;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.*;
import javax.xml.xpath.*;
import java.util.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class XPathDemo {
    private Document doc;

    public XPathDemo(String filePath) throws Exception {
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        doc = builder.parse(getClass().getClassLoader().getResourceAsStream(filePath));
    }

    public List<Node> query(String expression) throws XPathExpressionException {
        XPath xpath = XPathFactory.newInstance().newXPath();
        XPathExpression expr = xpath.compile(expression);
        NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

        List<Node> result = new ArrayList<>();
        for (int i = 0; i < nodes.getLength(); i++) {
            result.add(nodes.item(i));
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        XPathDemo demo = new XPathDemo("flights.xml");

        // 任务1：北京起飞的所有航班
        List<Node> beijingDepartures = demo.query("//flight[from='北京']");
        System.out.println("北京起飞的航班:");
        for (Node flight : beijingDepartures) {
            printFlightInfo(flight);
        }
        System.out.println("北京起飞的航班数: " + beijingDepartures.size());
        System.out.println("---------------------");

        // 任务2：到达上海的所有航班
        List<Node> shanghaiArrivals = demo.query("//flight[to='上海']");
        System.out.println("到达上海的航班:");
        for (Node flight : shanghaiArrivals) {
            printFlightInfo(flight);
        }
        System.out.println("到达上海的航班数: " + shanghaiArrivals.size());
        System.out.println("---------------------");

        // 任务3：早于08:00上海起飞的航班
        List<Node> earlyShanghaiFlights = demo.query("//flight[from='上海']");
        System.out.println("早于08:00从上海起飞的航班:");
        for (Node flight : earlyShanghaiFlights) {
            String departureTime = getNodeValue(flight, "departureTime").trim();
            if (departureTime.compareTo("08:00") < 0) {
                printFlightInfo(flight);
            }
        }
        System.out.println("早于08:00从上海起飞的航班数: " + earlyShanghaiFlights.size());
        System.out.println("---------------------");

        // 任务4：周2和周6都有执飞任务的航班
        // 先获取所有周二的航班号
        List<String> tuesdayFlightNumbers = new ArrayList<>();
        List<Node> tuesdayFlights = demo.query("//flight[day='周二']");
        for (Node flight : tuesdayFlights) {
            tuesdayFlightNumbers.add(getNodeValue(flight, "number"));
        }

        // 再获取所有周六的航班号
        List<String> saturdayFlightNumbers = new ArrayList<>();
        List<Node> saturdayFlights = demo.query("//flight[day='周六']");
        for (Node flight : saturdayFlights) {
            saturdayFlightNumbers.add(getNodeValue(flight, "number"));
        }

        // 找出同时在周二和周六出现的航班号
        tuesdayFlightNumbers.retainAll(saturdayFlightNumbers);

        // 输出结果
        System.out.println("周二和周六都有执飞的航班:");
        if (!tuesdayFlightNumbers.isEmpty()) {
            for (String flightNumber : tuesdayFlightNumbers) {
                System.out.println("航班号: " + flightNumber);
            }
            System.out.println("符合条件的航班数: " + tuesdayFlightNumbers.size());
        } else {
            System.out.println("没有在周二和周六都执飞的航班");
        }
    }

    private static void printFlightInfo(Node flight) throws Exception {
        String status = getNodeValue(flight, "status").trim().equals("0") ? "正常": "取消";
        System.out.println("航班号: " + getNodeValue(flight, "number") +
                ", 目的地: " + getNodeValue(flight, "to") +
                ", 出发日期: " + getNodeValue(flight, "departureDate") +
                ", 星期: " + getNodeValue(flight, "day") +
                ", 出发时间" + getNodeValue(flight, "departureTime") +
                ", 到达日期: " + getNodeValue(flight, "arrivalDate") +
                ", 到达时间: " + getNodeValue(flight, "arrivalTime") +
                ", 状态: " + status);
    }

    // 获取节点下子节点的值
    private static String getNodeValue(Node parent, String childNodeName) {
        NodeList children = parent.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            if (child.getNodeName().equals(childNodeName)) {
                return child.getTextContent();
            }
        }
        return "";
    }
}

